package com.gin.kotlin.gf2gamecommunity.base.composable

import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerDefaults
import androidx.compose.foundation.pager.PagerScope
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.util.fastForEachIndexed
import kotlinx.coroutines.launch

/**
 * 封装TabRow和HorizontalPager，并将其操作联动
 * @param tabSize 标签数量
 * @param tabsComposable 标签Composable
 * @param scrollable 标签栏是否可滚动
 * @param modifier Modifier
 * @param pageContent 页面内容
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TabRowPager(
    tabSize: Int,
    tabsComposable: @Composable (activeIndex: Int, onScrollToPage: (page: Int) -> Unit) -> Unit,
    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,
    modifier: Modifier = Modifier,
    scrollable: Boolean = false,
    fillHeight: Boolean = false,
    tabState: PagerState = rememberPagerState(pageCount = { tabSize }),
    pageContent: @Composable (PagerScope.(page: Int) -> Unit)
) {
    var activeIndex by remember { mutableIntStateOf(0) }
    val scope = rememberCoroutineScope()
    val tabs = @Composable { tabsComposable(activeIndex) { scope.launch { tabState.scrollToPage(it) } } }

    Column(modifier = modifier) {
        if (scrollable)
            ScrollableTabRow(selectedTabIndex = activeIndex, tabs = tabs)
        else
            PrimaryTabRow(selectedTabIndex = activeIndex, tabs = tabs)
        HorizontalPager(state = tabState,
            beyondViewportPageCount = beyondViewportPageCount,
            modifier = if (fillHeight) Modifier.weight(1f) else Modifier,
            verticalAlignment = Alignment.Top,
            key = { it },
            flingBehavior = PagerDefaults.flingBehavior(state = tabState,
                snapPositionalThreshold = 0.3f
            ),
            pageContent = pageContent)
        LaunchedEffect(tabState) { snapshotFlow { tabState.currentPage }.collect { page -> activeIndex = page } }
    }
}

/**
 * 标签信息
 * @param text 文字
 * @param iconDrawable Drawable形式的图标，图标二选一，本项优先
 * @param iconVector ImageVector形式的图标，图标二选一
 * @param content 页面内容
 * @constructor
 */
data class TabInfo(
    val text: String? = null,
    @DrawableRes val iconDrawable: Int? = null,
    val iconVector: ImageVector? = null,
    val icon: @Composable () -> Unit = { },
    val content: @Composable (page: Int) -> Unit,
)

@Composable
fun TabRowPager(
    tabList: List<TabInfo>,
    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,
    fillHeight: Boolean = false,
    scrollable: Boolean = false,
    tabState: PagerState = rememberPagerState(pageCount = { tabList.size }),
    modifier: Modifier = Modifier
) {
    TabRowPager(
        tabSize = tabList.size,
        modifier = modifier,
        tabState = tabState,
        fillHeight = fillHeight,
        beyondViewportPageCount = beyondViewportPageCount,
        scrollable = scrollable,
        tabsComposable = { activeIndex, onScrollToPage ->
            tabList.fastForEachIndexed { index, tabInfo ->
                Tab(selected = activeIndex == index, onClick = { onScrollToPage(index) }, text = {
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        tabInfo.apply {
                            // Icon
                            iconDrawable?.let { Icon(painterResource(it), contentDescription = null) }
                                ?: iconVector?.let { Icon(it, contentDescription = null) }
                                ?: icon()
                            text?.let { Text(it) }
                        }
                    }
                })
            }
        },
    ) { page -> tabList[page].content(page) }
}